﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web.Caching;
using System.Web;
using System.Text.RegularExpressions;
using System.IO.Compression;

namespace AjaxControlToolkitEx
{

    public class MinHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            HttpResponse objResponse = context.Response;
            string file = context.Request.PhysicalPath;            

            switch (Path.GetExtension(file).ToLower())
            {
                default:
                    return;
                case ".js":
                    objResponse.ContentType = "text/javascript";
                    break;
                case ".css":
                    objResponse.ContentType = "text/css";
                    break;
                case ".png":
                    objResponse.ContentType = "image/png";
                    objResponse.Charset = string.Empty;
                    break;
                case ".gif":
                    objResponse.ContentType = "image/gif";
                    objResponse.Charset = string.Empty;
                    break;
            }


            switch (Path.GetExtension(file).ToLower())
            {
                case ".png":
                case ".gif":
                    {
                        //Compress(context);
                        objResponse.WriteFile(file);
                    }
                    break;
                case ".js":
                case ".css":
                    {
                        TextReader s = new StreamReader(file);
                        string data = s.ReadToEnd();
                        s.Close();
                        s.Dispose();
                        Microsoft.Ajax.Utilities.Minifier min = new Microsoft.Ajax.Utilities.Minifier();
                        switch (Path.GetExtension(file).ToLower())
                        {
                            case ".js":
                                data = min.MinifyJavaScript(data);
                                break;
                            case ".css":
                                data = min.MinifyStyleSheet(data);
                                break;
                        }
                        objResponse.Write(data);
                    }
                    break;
            }

            objResponse.Cache.SetCacheability(HttpCacheability.Public);
            objResponse.Cache.SetExpires(DateTime.Today.AddDays(1));
            objResponse.Cache.SetRevalidation(HttpCacheRevalidation.None);
        }

        #region Compression

        private const string GZIP = "gzip";
        private const string DEFLATE = "deflate";

        private static void Compress(HttpContext context)
        {
            if (context.Request.UserAgent != null && context.Request.UserAgent.Contains("MSIE 6"))
                return;

            if (IsEncodingAccepted(GZIP))
            {
                context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
                SetEncoding(GZIP);
            }
            else if (IsEncodingAccepted(DEFLATE))
            {
                context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
                SetEncoding(DEFLATE);
            }
        }

        /// <summary>
        /// Checks the request headers to see if the specified
        /// encoding is accepted by the client.
        /// </summary>
        private static bool IsEncodingAccepted(string encoding)
        {
            return HttpContext.Current.Request.Headers["Accept-encoding"] != null && HttpContext.Current.Request.Headers["Accept-encoding"].Contains(encoding);
        }

        /// <summary>
        /// Adds the specified encoding to the response headers.
        /// </summary>
        /// <param name="encoding"></param>
        private static void SetEncoding(string encoding)
        {
            HttpContext.Current.Response.AppendHeader("Content-encoding", encoding);
        }

        #endregion

        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
    }

}
